﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace LL.Common
{

    public static class FlagEnumExtensions
    {
        public static bool IsDefined<T>(this Enum item, T compared)
        {
            return item.Cast<int>() == compared.Cast<int>()
                    || (item.Cast<int>() | compared.Cast<int>()) == item.Cast<int>();
        }

        public static IEnumerable<Enum> GetDefinedValues(this Enum commandFlags)
        {
            return Enum.GetValues(commandFlags.GetType())
                    .Cast<Enum>()
                    .Where(d => commandFlags.IsDefined(d));
        }
        public static IEnumerable<T> GetDefinedValues<T>(this Enum commandFlags)
        {
            return Enum.GetValues(commandFlags.GetType())
                       .Cast<T>()
                       .Where(d => commandFlags.IsDefined(d));
        }

        public static IEnumerable<Enum> GetCandidatedValues(this Enum commandFlags, params Enum[] flags)
        {
            return commandFlags.GetDefinedValues().Where(d => flags.Contains(d));
        }
        public static IEnumerable<T> GetCandidatedValues<T>(this Enum commandFlags, params Enum[] flags)
        {
            return commandFlags.GetDefinedValues().Where(d => flags.Contains(d)).Cast<T>();
        }

        public static int[] GetDefinedIntValues(this Enum commandFlags)
        {
            return commandFlags.GetDefinedValues().Cast<int>().ToArray();
        }
        public static string[] GetDefinedStringValues(this Enum commandFlags)
        {
            return commandFlags.GetDefinedValues()
                .Select(d => d.Cast<int>().ToString())
                .ToArray();
        }

        public static int[] GetCandidatedIntValues(this Enum commandFlags, params Enum[] flags)
        {
            return commandFlags.GetCandidatedValues(flags).Cast<int>().ToArray();
        }
        public static string[] GetCandidatedStringValues(this Enum commandFlags, params Enum[] flags)
        {
            return commandFlags.GetCandidatedValues(flags).Cast<int>().Select(d => d.ToString()).ToArray();
        }
    }

}